home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol07 / 02 / controls / ctldlg.c next >
C/C++ Source or Header  |  1992-02-29  |  12KB  |  450 lines

  1. /*
  2.  * CTLDLG.C
  3.  *
  4.  * Routines to interface the DLL custom control to
  5.  * the Dialog Editor.
  6.  *
  7.  * Version 1.1, October 1991, Kraig Brockschmidt
  8.  */
  9.  
  10.  
  11. #include <windows.h>
  12. #include "muscrdll.h"
  13.  
  14.  
  15. /*
  16.  * Globals for use in the Style Dialog.
  17.  */
  18.  
  19. HANDLE      hStyleMem;
  20. LPFNSTRTOID lpStrToId;
  21. LPFNIDTOSTR lpIdToStr;
  22.  
  23. extern HANDLE hgInst;
  24.  
  25. WORD PASCAL WFormStyleFlags(HWND);
  26. BOOL PASCAL FRangePositionCheck(HWND hDlg);
  27.  
  28.  
  29.  
  30. /*
  31.  * HCtlInfo
  32.  *
  33.  * Purpose:
  34.  *  Provides basic information about the control to the caller, which
  35.  *  is usually the Dialog Editor or any other possible future program
  36.  *  that edits dialog tempaltes and needs to know about controls.
  37.  *
  38.  *  The information is contained in a global memory object of type
  39.  *  INFO.  This memory object becomes the responsibility of the
  40.  *  caller.
  41.  *
  42.  * Parameters:
  43.  *  none
  44.  *
  45.  * Return Value:
  46.  *  HANDLE      Handle to a Global memory object or NULL if it cannot
  47.  *              be allocated.  The caller must free the memory.
  48.  *              ALLOCATE WITH GMEM_DDESHARE!
  49.  *
  50.  */
  51.  
  52. HANDLE FAR PASCAL HCtlInfo(void)
  53.     {
  54.     HANDLE      hMem;
  55.     LPCTLINFO   pCtlInfo;
  56.  
  57.     //Allocate a INFO struct
  58.     hMem=GlobalAlloc(GMEM_MOVEABLE, sizeof(CTLINFO));
  59.  
  60.     if (hMem==NULL)
  61.         return NULL;
  62.  
  63.     //Get the pointers we need.
  64.     pCtlInfo=(LPCTLINFO)GlobalLock(hMem);
  65.  
  66.     if (pCtlInfo==NULL)
  67.         {
  68.         GlobalFree(hMem);
  69.         return NULL;
  70.         }
  71.  
  72.     //Set the overall control info.
  73.     pCtlInfo->wVersion=0100;
  74.     pCtlInfo->wCtlTypes=2;
  75.     LoadString(hgInst, IDS_CLASSNAME, pCtlInfo->szClass, CTLCLASS);
  76.     LoadString(hgInst, IDS_FULLNAME,  pCtlInfo->szTitle, CTLTITLE);
  77.  
  78.     //Set the types
  79.     pCtlInfo->Type[0].wType  =0;
  80.     pCtlInfo->Type[0].wWidth =11;
  81.     pCtlInfo->Type[0].wHeight=20;
  82.     pCtlInfo->Type[0].dwStyle=WS_CHILD | WS_VISIBLE | MSS_VERTICAL;
  83.     LoadString(hgInst, IDS_VERTICAL, pCtlInfo->Type[0].szDescr, CTLDESCR);
  84.  
  85.     //Set the types
  86.     pCtlInfo->Type[1].wType  =0;
  87.     pCtlInfo->Type[1].wWidth =21;
  88.     pCtlInfo->Type[1].wHeight=12;
  89.     pCtlInfo->Type[1].dwStyle=WS_CHILD | WS_VISIBLE | MSS_HORIZONTAL;
  90.     LoadString(hgInst, IDS_HORIZONTAL, pCtlInfo->Type[1].szDescr, CTLDESCR);
  91.  
  92.     //Give the memory to the Dialog Editor.
  93.     GlobalUnlock(hMem);
  94.     return hMem;
  95.     }
  96.  
  97.  
  98.  
  99.  
  100. /*
  101.  * WTranslateCtlFlags
  102.  *
  103.  * Purpose:
  104.  *  Translates the class style flags into a text string to be used in the
  105.  *  output of the Dialog Editor in a CONTROL statement of a dialog script
  106.  *  (i.e. SS_ICON or BS_OWNERDRAW).  The same text as used in the
  107.  *  incldue file should be used here.
  108.  *
  109.  *  Null-terminate the string for safety since we don't know what the
  110.  *  Dialog Editor might do.
  111.  *
  112.  * Parameters:
  113.  *  dwStyle     DWORD containing the style bits.
  114.  *  psz         LPSTR pointer to string to receive the style text.
  115.  *  cchMax      WORD maximum length of the string.
  116.  *
  117.  * Return Value:
  118.  *  WORD        Number of characters filled in the buffer.  0 on an error.
  119.  *
  120.  */
  121.  
  122. WORD FAR PASCAL WTranslateCtlFlags(DWORD dwStyle, LPSTR psz, WORD cchMax)
  123.     {
  124.     WORD        cch=0;
  125.     LPSTR       pszT;
  126.  
  127.     pszT=psz;
  128.  
  129.     //Use one of these two exclusive styles.
  130.     if (dwStyle & MSS_HORIZONTAL)
  131.         cch=LoadString(hgInst, IDS_MSS_HORIZONTAL, pszT, cchMax);
  132.     else
  133.         cch=LoadString(hgInst, IDS_MSS_VERTICAL, pszT, cchMax);
  134.  
  135.     //Adjust remaining number of characters we can store.
  136.     cchMax-=cch;
  137.     pszT+=cch;
  138.  
  139.     //Any of these stings can be concatenated.
  140.     if (MSS_TEXTHASRANGE & dwStyle)
  141.         {
  142.         cch=LoadString(hgInst, IDS_MSS_TEXTHASRANGE, pszT, cchMax);
  143.         pszT+=cch;
  144.         cchMax-=cch;
  145.         }
  146.  
  147.     if (MSS_NOPEGSCROLL & dwStyle)
  148.         {
  149.         cch=LoadString(hgInst, IDS_MSS_NOPEGSCROLL, pszT, cchMax);
  150.         pszT+=cch;
  151.         cchMax-=cch;
  152.         }
  153.  
  154.     if (MSS_INVERTRANGE & dwStyle)
  155.         {
  156.         cch=LoadString(hgInst, IDS_MSS_INVERTRANGE, pszT, cchMax);
  157.         pszT+=cch;
  158.         cchMax-=cch;
  159.         }
  160.  
  161.     /*
  162.      * Chop off the string 2 characters from the end since we have an extra
  163.      * '| 'there.
  164.      */
  165.     cch=lstrlen(psz)-2;
  166.     *(psz+cch)=0;
  167.  
  168.     return cch;
  169.     }
  170.  
  171.  
  172.  
  173.  
  174. /*
  175.  * FShowCtlStyleDlg
  176.  *
  177.  * Purcdctl.cpose:
  178.  *  Requests the control library to display a dialog box that
  179.  *  allows editing of the control's styles.  The fields in a SYTLE
  180.  *  structure must be set according to what the window is and what
  181.  *  it contains.
  182.  *
  183.  * Parameters:
  184.  *  hWnd        HWND to the control.
  185.  *  hMem        HANDLE to global memory of the STYLE structure.
  186.  *  lpfnStrToId LPFNSTRTOID pointer to Dialog Editor function that
  187.  *              returns the include file symbol for a given ID.
  188.  *  lpfnIdToStr LPFNIDTOSTR pointer to Dialog Edit function that
  189.  *              returns the ID of a given symbol.
  190.  *
  191.  * Return Value:
  192.  *  BOOL        TRUE if the STYLE structure was changed, FALSE
  193.  *              otherwise.
  194.  */
  195.  
  196. BOOL FAR PASCAL FShowCtlStyleDlg(HWND hWnd, HANDLE hMem,
  197.                                  LPFNSTRTOID lpfnStrToId,
  198.                                  LPFNIDTOSTR lpfnIdToStr)
  199.     {
  200.     FARPROC     lpStyleDlgProc;
  201.     BOOL        bReturn;
  202.  
  203.     //Save the vital information for the dialog.
  204.     hStyleMem=hMem;
  205.     lpStrToId=lpfnStrToId;
  206.     lpIdToStr=lpfnIdToStr;
  207.  
  208.     //Show dialog box
  209.     lpStyleDlgProc=MakeProcInstance((FARPROC)FCtlStyleDlgProc, hgInst);
  210.  
  211.     bReturn=DialogBox(hgInst, MAKEINTRESOURCE(IDD_STYLEDIALOG),
  212.                       hWnd, lpStyleDlgProc);
  213.  
  214.     FreeProcInstance(lpStyleDlgProc);
  215.  
  216.     return bReturn;
  217.     }
  218.  
  219.  
  220.  
  221.  
  222.  
  223. /*
  224.  * FCtlStyleDlgProc
  225.  *
  226.  * Purpose:
  227.  *  The dialog function for the dialog box displayed when the XXXXStyle
  228.  *  function is called.  This is a normal dialog box proc in all respects.
  229.  *
  230.  * Parameters:
  231.  *  standard
  232.  *
  233.  * Return Value:
  234.  *  BOOL        Standard for a dialog box.
  235.  */
  236.  
  237. BOOL FAR PASCAL FCtlStyleDlgProc(HWND hDlg, WORD wMessage, WORD wParam, LONG lParam)
  238.     {
  239.     LPCTLSTYLE      lpCtlStyle;
  240.     char            szTemp[32];
  241.     DWORD           dwID;
  242.     WORD            wStyle;
  243.     WORD            wWinStyle;
  244.  
  245.     switch (wMessage)
  246.         {
  247.         case WM_INITDIALOG:
  248.             lpCtlStyle=(LPCTLSTYLE)GlobalLock(hStyleMem);
  249.  
  250.             if (lpCtlStyle==NULL)
  251.                 return FALSE;
  252.  
  253.             (*lpIdToStr)(lpCtlStyle->wId, (LPSTR)szTemp, 32);
  254.             SetDlgItemText(hDlg, ID_IDEDIT, szTemp);
  255.             SetDlgItemText(hDlg, ID_TEXTEDIT, lpCtlStyle->szTitle);
  256.  
  257.             wStyle=LOWORD(lpCtlStyle->dwStyle);
  258.  
  259.             //There's gotta be a better way to do this.
  260.             if (wStyle & MSS_VERTICAL)
  261.                 CheckRadioButton(hDlg, ID_RADIOVERTICAL,
  262.                                  ID_RADIOHORIZONTAL, ID_RADIOVERTICAL);
  263.  
  264.             if (wStyle & MSS_HORIZONTAL)
  265.                 CheckRadioButton(hDlg, ID_RADIOVERTICAL,
  266.                                  ID_RADIOHORIZONTAL, ID_RADIOHORIZONTAL);
  267.  
  268.             if (wStyle & MSS_TEXTHASRANGE)
  269.                 CheckDlgButton(hDlg, ID_CHECKTEXTHASRANGE, 1);
  270.  
  271.             if (wStyle & MSS_NOPEGSCROLL)
  272.                 CheckDlgButton(hDlg, ID_CHECKNOPEGSCROLL, 1);
  273.  
  274.             if (wStyle & MSS_INVERTRANGE)
  275.                 CheckDlgButton(hDlg, ID_CHECKINVERTRANGE, 1);
  276.  
  277.             GlobalUnlock(hStyleMem);
  278.             break;
  279.  
  280.  
  281.         case WM_COMMAND:
  282.             switch (wParam)
  283.                 {
  284.                 /*
  285.                  * Check for valid range text in the Text field if the
  286.                  * Text Has Range box is checked.
  287.                  */
  288.  
  289.                 case ID_CHECKTEXTHASRANGE:
  290.                     if (HIWORD(lParam)==BN_CLICKED)
  291.                         {
  292.                         if (IsDlgButtonChecked(hDlg, wParam))
  293.                             FRangePositionCheck(hDlg);
  294.                         }
  295.                     break;
  296.  
  297.  
  298.                 case IDOK:
  299.                     //Verify the range text again.
  300.                     if (IsDlgButtonChecked(hDlg, ID_CHECKTEXTHASRANGE))
  301.                         {
  302.                         if (!FRangePositionCheck(hDlg))
  303.                             return TRUE;
  304.                         }
  305.  
  306.                     //Make sure the identifier works.
  307.                     GetDlgItemText(hDlg, ID_IDEDIT, szTemp, 32);
  308.                     dwID=(*lpStrToId)(szTemp);
  309.  
  310.  
  311.                     if (LOWORD(dwID))
  312.                         {
  313.                         lpCtlStyle=(LPCTLSTYLE)GlobalLock(hStyleMem);
  314.  
  315.                         if (lpCtlStyle!=NULL)
  316.                             {
  317.                             //Save the Style, ID, and text.
  318.                             wStyle=WFormStyleFlags(hDlg);
  319.                             wWinStyle=HIWORD(lpCtlStyle->dwStyle);
  320.                             lpCtlStyle->dwStyle=MAKELONG(wStyle, wWinStyle);
  321.  
  322.                             lpCtlStyle->wId=HIWORD(dwID);
  323.                             GetDlgItemText(hDlg, ID_TEXTEDIT, lpCtlStyle->szTitle, CTLTITLE);
  324.  
  325.                             GlobalUnlock(hStyleMem);
  326.                             EndDialog(hDlg, TRUE);
  327.                             }
  328.                         else
  329.                             EndDialog(hDlg, FALSE);
  330.                         }
  331.  
  332.                     break;
  333.  
  334.                 case IDCANCEL:
  335.                     EndDialog(hDlg, FALSE);
  336.                     break;
  337.  
  338.                 default:
  339.                     break;
  340.                 }
  341.             break;
  342.  
  343.         default:
  344.             return FALSE;
  345.         }
  346.  
  347.     return TRUE;
  348.     }
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356. /*
  357.  * WFormStyleFlags
  358.  *
  359.  * Purpose:
  360.  *  Returns a WORD with flags set to whatever options are checked in
  361.  *  the dialog box.  It is up to the implementer of the dialog box to
  362.  *  code the exact bit fields in this function.
  363.  *
  364.  * Parameters:
  365.  *  hDlg        HWND of the style dialog.
  366.  *
  367.  * Return Value:
  368.  *  WORD        Style Flags value.
  369.  */
  370.  
  371. WORD PASCAL WFormStyleFlags(HWND hDlg)
  372.     {
  373.     WORD    wStyle=0;
  374.  
  375.     if (IsDlgButtonChecked(hDlg, ID_RADIOVERTICAL))
  376.         wStyle |= MSS_VERTICAL;
  377.     else
  378.         wStyle |= MSS_HORIZONTAL;
  379.  
  380.     if (IsDlgButtonChecked(hDlg, ID_CHECKTEXTHASRANGE))
  381.         wStyle |= MSS_TEXTHASRANGE;
  382.  
  383.     if (IsDlgButtonChecked(hDlg, ID_CHECKNOPEGSCROLL))
  384.         wStyle |= MSS_NOPEGSCROLL;
  385.  
  386.     if (IsDlgButtonChecked(hDlg, ID_CHECKINVERTRANGE))
  387.         wStyle |= MSS_INVERTRANGE;
  388.  
  389.     return wStyle;
  390.     }
  391.  
  392.  
  393.  
  394.  
  395.  
  396. /*
  397.  * FRangePositionCheck
  398.  *
  399.  * Purpose:
  400.  *  Checks if the control text contains a valid string and that
  401.  *  the initial position is within the given range.
  402.  *
  403.  * Parameters:
  404.  *  hDlg            HWND of the style dialog.
  405.  *
  406.  * Return Value:
  407.  *  BOOL            TRUE if the text is valid, FALSE otherwise.
  408.  *
  409.  */
  410.  
  411. BOOL PASCAL FRangePositionCheck(HWND hDlg)
  412.     {
  413.     HWND        hEdit;
  414.     char        szTemp1[60];
  415.     char        szTemp2[60];
  416.     BOOL        fTextOK;
  417.     short       iMin;
  418.     short       iMax;
  419.     short       iPos;
  420.  
  421.     /*
  422.      * We checked the MSS_TEXTHASRANGE box, so verify that there
  423.      * is valid text in the Text edit control.  If not, just
  424.      * cue the user with a beep and a SetFocus.
  425.      */
  426.     hEdit=GetDlgItem(hDlg, ID_TEXTEDIT);
  427.     GetWindowText(hEdit, szTemp1, 60);
  428.  
  429.     fTextOK=FTextParse(szTemp1, &iMin, &iMax, &iPos);
  430.  
  431.     if (fTextOK && (iPos < iMin || iPos > iMax))
  432.         {
  433.         LoadString(hgInst, IDS_CLASSNAME,  szTemp1, 60);
  434.         LoadString(hgInst, IDS_RANGEERROR, szTemp2, 60);
  435.  
  436.         MessageBox(hDlg, szTemp2, szTemp1, MB_OK | MB_ICONEXCLAMATION);
  437.         SetFocus(hEdit);
  438.         SendMessage(hEdit, EM_SETSEL, 0, MAKELONG(0, 32767));
  439.         }
  440.  
  441.     if (!fTextOK)
  442.         {
  443.         MessageBeep(0);
  444.         SetFocus(hEdit);
  445.         SendMessage(hEdit, EM_SETSEL, 0, MAKELONG(0, 32767));
  446.         }
  447.  
  448.     return fTextOK;
  449.     }
  450.